package com.oa.common;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.oa.common.result.Result;
import com.oa.common.result.SystemCode;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.web.authentication.SimpleUrlAuthenticationFailureHandler;
import org.springframework.util.StringUtils;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

/**
 * @author cuichao
 * 复合型认证失败执行器
 */
public class ComplexAuthenticationFailureHandler extends SimpleUrlAuthenticationFailureHandler {

    private final Log logger = LogFactory.getLog(getClass());

    private final ObjectMapper mapper = new ObjectMapper();


    @Override
    public void onAuthenticationFailure(HttpServletRequest request, HttpServletResponse response, AuthenticationException exception) throws IOException, ServletException {
        String accept = request.getHeader(HttpHeaders.ACCEPT);

        boolean isJsonAccept = StringUtils.hasText(accept) && accept.contains(MediaType.APPLICATION_JSON_VALUE);
        boolean isJsonResponse = StringUtils.hasText(request.getParameter("type")) && "json".equals(request.getParameter("type"));

        if (isJsonAccept || isJsonResponse) {
            if (!response.isCommitted()) {
                logger.debug("No failure URL set, sending 401 Unauthorized error");
                response.setStatus(HttpStatus.UNAUTHORIZED.value());
                response.setCharacterEncoding("UTF-8");
                response.setHeader(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE);
                Result failure = Result.failure(SystemCode.unauthorized,  HttpStatus.UNAUTHORIZED.getReasonPhrase());
                mapper.writeValue(response.getWriter(), failure);
            }
            return;
        }

        defaultAuthenticationFailureProcessor(request, response, exception);
    }

    private void defaultAuthenticationFailureProcessor(HttpServletRequest request, HttpServletResponse response, AuthenticationException exception) throws IOException, ServletException {
        super.onAuthenticationFailure(request, response, exception);
    }
}
